using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;

namespace DynamicDNS.Provider.BaseProvider
{
    /// <summary>
    /// This abstract class provides basic implementation for webbased DynmaicDNS Provider
    /// </summary>
    public abstract class DynamicDNSWebBaseProvider : DynamicDNS.Provider.BaseProvider.IDynamicDNSBaseProvider
    {
        /// <summary>
        /// Contains the URL, which shall be contacted
        /// </summary>
        protected string Url;

        /// <summary>
        /// Provides a possibility to set additional Headers for the HTTPWebRequest. It is used f.e. for the Basic Authentication
        /// </summary>
        protected Dictionary<string, string> Headers = new Dictionary<string, string>();


        /// <summary>
        /// This method processes the webbased update for a DNS Entry
        /// </summary>
        /// <returns>DynamicDNSUpdateResult indicates, whether an Update was successfull or not.</returns>
        public DynamicDNSUpdateResult UpdateDNSEntry()
        {
            string response;
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(Url.ToString());
            // Add Headers
            foreach (KeyValuePair<string, string> header in Headers)
            {
                httpWebRequest.Headers.Add(header.Key, header.Value);
            }
            
            httpWebRequest.UserAgent = "DynamicDNS Library";
            HttpWebResponse httpWebResponse;

            try
            {
                httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            }
            catch (Exception e)
            {
                
                throw new DynamicDNSCommunicationException("A network error occured during communication.",e);
            }

            using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
            {
                response = sr.ReadToEnd();
            }
            return CheckResponse(response);
        }

        /// <summary>
        /// This method analyzes the Response, if the update has been successfull.
        /// </summary>
        /// <param name="response">The Response, which has been sent by the webserver</param>
        /// <returns>DynamicDNSUpdateResult indicates, whether an Update was successful or not.</returns>
        protected virtual DynamicDNSUpdateResult CheckResponse(string response)
        {
            //Sample processing for dynDns.org
            switch (response.Substring(0, response.IndexOf(" ")).ToLower())
            {
                case "good":
                    // The update was successful, and the hostname is now updated
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.OK, "");
                     
                case "nochg":
                    // The update changed no settings, and is considered abusive.Additional nochg updates will cause the hostname to become blocked
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Unchanged, "");
                     
                case "badsys":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError1);
                     
                case "badagent":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError2);
                     
                case "badauth":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError3);
                     
                case "!donator":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError4);
                     
                case "notfqdn":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError5);
                     
                case "nohost":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError6);
                     
                case "!yours":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError7);
                     
                case "abuse":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError8);
                     
                case "numhost":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError9);
                     
                case "dnserr":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError10);
                     
                case "911":
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError11);
                     
                default:
                    return  new DynamicDNSUpdateResult(DynamicDNSStatus.Error, DynamicDNS.StringRessources.dynDNSError12);
                     
            }
        }
    }
}
